using AppToolKit.Core.Context;
using AppToolKit.Core.Logging;
using Common.Logging;
using System;
using System.Collections.Generic;
namespace AppToolKit.Business.Plugin
{
	public abstract class ImplementManager<TInf, TIdent> : IImplementManager<TInf, TIdent> where TIdent : IImplementIdent, new()
	{
		private ILog logger_ = LogManager.GetLogger(DefaultLogger.LOGGER_NAME);
		protected Dictionary<string, TInf> map_ = new Dictionary<string, TInf>();
		protected List<TIdent> idents_ = new List<TIdent>();
		protected string DefaultIdent = string.Empty;
		[AutoWiring]
		public IContextManager ContextHandler
		{
			protected get;
			set;
		}
		public virtual void Register(TIdent ident, TInf instance)
		{
			if (!this.map_.ContainsKey(ident.Value))
			{
				this.idents_.Add(ident);
				this.logger_.Debug(string.Format("register card:value,{0},descript{1}", ident.Value, ident.Descript));
			}
			else
			{
				this.logger_.Debug(string.Format("reset register card:value,{0},descript{1}", ident.Value, ident.Descript));
			}
			this.map_[ident.Value] = instance;
		}
		public virtual void Clear()
		{
			this.idents_.Clear();
			this.map_.Clear();
		}
		public virtual void Register<TImpl>(TImpl instance) where TImpl : TInf
		{
			ImplementAttrParams code = ImplementAttrHelper.GetCode<TImpl>();
			if (this.map_.ContainsKey(code.Value))
			{
				throw new Exception("dup register");
			}
			if (code.Default)
			{
				this.logger_.Debug(string.Format("default is {0}", code.Value));
				if (this.DefaultIdent != string.Empty)
				{
					throw new Exception(string.Format("default implate also is {0}", this.DefaultIdent));
				}
				this.DefaultIdent = code.Value;
			}
			TIdent ident = (default(TIdent) == null) ? Activator.CreateInstance<TIdent>() : default(TIdent);
			ident.Value = code.Value;
			ident.Descript = code.Descript;
			this.AfterIdentCreated(ident);
			this.Register(ident, (TInf)instance);
		}
		protected virtual void AfterIdentCreated(TIdent ident)
		{
		}
		public virtual TInf GetImplement(string ident)
		{
			string key = ident.Trim();
			if (!this.map_.ContainsKey(key))
			{
				this.logger_.Debug(string.Format("not found card type{0}//", ident));
				throw new Exception(string.Format("({0}) class not registed", ident));
			}
			return this.map_[key];
		}
		public virtual TInf GetDefaultImplement()
		{
			return this.GetImplement(this.DefaultIdent);
		}
		public virtual List<TIdent> GetAllIdent()
		{
			return this.idents_;
		}
	}
}
